use crate::config::Config;
use crate::CodeSnippet;
use skim::prelude::*;

const DELIMITER: &str = "\t";

// Run Skim interface
pub fn run_skim_interface(snippets: Vec<CodeSnippet>, _config: &Config) -> Option<CodeSnippet> {
    // Get current executable path
    let current_exe = std::env::current_exe().ok()?;
    let exe_path = current_exe.to_string_lossy();

    // Use the current executable's preview command as the preview command
    // Format: tag	file_path	line_number, preview command needs file path and line number
    let preview_cmd = format!("{} preview {{3}} {{1}}", exe_path);

    let options = SkimOptionsBuilder::default()
        .exact(true)
        .preview_window(Some("right:70%"))
        .multi(false)
        .reverse(false)
        .preview(Some(&preview_cmd))
        .prompt(Some("🔍 "))
        .delimiter(Some(DELIMITER))
        .build()
        .unwrap();

    // Use SkimItemReader to support nth option
    let item_reader_option = SkimItemReaderOption::default()
        .nth("1,2") // Use the 2nd column (tag) as the matching key
        .delimiter(DELIMITER)
        .with_nth("2")
        .build();

    let item_reader = SkimItemReader::new(item_reader_option);

    // Build input data
    let mut input_data = String::new();
    for snippet in snippets.iter() {
        let line = format!(
            "{}\t{}\t{}\t{}\n",
            snippet.line_number,
            snippet.tag,
            snippet.file_path.to_string_lossy(),
            snippet.id
        );
        input_data.push_str(&line);
    }

    let items = item_reader.of_bufread(std::io::Cursor::new(input_data));
    let output = match Skim::run_with(&options, Some(items)) {
        Some(output) => output,
        None => {
            return None;
        }
    };

    if output.is_abort {
        return None;
    }

    let selected_items = output.selected_items;

    if let Some(selected) = selected_items.first() {
        let selected_text = selected.output().to_string();
        // Extract ID from the selected text (4th column, tab-separated)
        let selected_id = selected_text.split(DELIMITER).nth(3).unwrap_or("").trim();

        // Try to parse the ID as a number
        if let Ok(id) = selected_id.parse::<usize>() {
            // Directly index the corresponding code snippet by ID
            if let Some(found_snippet) = snippets.iter().find(|s| s.id == id) {
                return Some(found_snippet.clone());
            }
        }
    }

    None
}
